package com.wmyg.antifake.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.wmyg.antifake.bean.*;
import com.wmyg.antifake.message.EnterBody;
import com.wmyg.antifake.message.Message;
import com.wmyg.antifake.service.FabricService;
import com.wmyg.antifake.service.QrProductService;
import com.wmyg.antifake.utils.*;
import com.wmyg.antifake.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@RestController
@RequestMapping(value = "/qrcode")
@Slf4j
public class QRCodeController {

    private static final String SUFFIX_2003 = ".xls";
    private static final String SUFFIX_2007 = ".xlsx";
    private static final String EXCEL_PATH = "excel/";

    @Value("${files.uploadFolder}")
    private String uploadBasePath;

    @Autowired
    FabricService fabricService;

    @Autowired
    QrProductService qrProductService;

    @GetMapping("/import2")
    public Message enterQRInfos(@RequestBody EnterBody enterBody) {
        return fabricService.enterTotalList(enterBody.getItems(), enterBody.getProducer());
    }

    @RequestMapping(method = RequestMethod.GET,value = "/toUpload")
    public ModelAndView toUpload(ModelAndView mv){
        mv.setViewName("product/uploadQRCodes");
        return mv;
    }

    @RequestMapping(method = RequestMethod.GET,value = "/toGenCodes")
    public ModelAndView toGenCodes(ModelAndView mv,String qrcodeId){
        if(StringUtils.isNotEmpty(qrcodeId)){
            Qrcode qrcode=fabricService.findPrimaryId(Long.parseLong(qrcodeId));
            qrcode.setProductTimeStr(DateUtil.fomatDateStr(qrcode.getProductTime(),"yyyy-MM-dd hh:mm"));
            mv.addObject("qrCode",qrcode);
        }else{
            Qrcode qr= new Qrcode();
            qr.setProductBatch(RandUtil.genRandNumber());
            mv.addObject("qrCode",qr);
        }
        mv.setViewName("product/genQRCodes");
        return mv;
    }

    @RequestMapping(method = RequestMethod.POST,value = "/genCodes")
    @ResponseBody
    public Map<String,Object> genCodes(HttpServletRequest request, UnitInfo uParam, String packHierQuant) throws ExecutionException, InterruptedException {
        Enumeration enu=request.getParameterNames();
        while(enu.hasMoreElements()){
            String paraName=(String)enu.nextElement();
            log.info(paraName+": "+request.getParameter(paraName));
        }
        uParam.setEnvironment("0");
        uParam.setMaterialBatch("0");
        uParam.setProductTime(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
        HttpSession session = request.getSession();
        User user = (User)session.getAttribute("loginUser");
        String userId = user == null ? "no user" : user.getUserId().toString();

        String[] packArr = packHierQuant.replaceAll("[0-9]|\\*", " ").replaceAll(" +", " ").trim().split(" ");
        String[] sNumArr = packHierQuant.replaceAll("[\\u4e00-\\u9fa5]|\\*", " ").replaceAll(" +", " ").trim().split(" ");

        Long qrcodeId=StringUtils.isEmpty(uParam.getQrcodeId())?null:Long.parseLong(uParam.getQrcodeId());
        Qrcode qrcode=new Qrcode(qrcodeId,uParam.getItemNo(),uParam.getEnterBatch(),uParam.getEnvironment(),uParam.getMaterialBatch(),
                0,0,0,0,new Date(),userId, DateUtil.fomatToDate(uParam.getProductTime(),"yyyy-MM-dd hh:mm"),null,null,null,null,null,null,null);

        for(int i=0;i<packArr.length;i++){
            switch (packArr[i]){
                case "箱":
                    qrcode.setCaseNum(Integer.parseInt(sNumArr[i]));
                    break;
                case "盒":
                    qrcode.setBoxNum(Integer.parseInt(sNumArr[i]));
                    break;
                case "包":
                    qrcode.setPackageNum(Integer.parseInt(sNumArr[i]));
                    break;
            }
        }
        int i = fabricService.insertOrUpdate(qrcode);
        Future<Map<String,Object>> baseResultFu=fabricService.genCodes(uParam,packArr,sNumArr,userId,qrcode.getQrcodeId());
        Map<String,Object>  baseResult=baseResultFu.get();
        return baseResult;
    }

    @RequestMapping(value = "/downloadCodes", method = RequestMethod.GET)
    public void downloadCodes(String filename, HttpServletResponse response) throws Exception{

        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=" + filename);
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(new File(uploadBasePath + EXCEL_PATH + filename)));
            int i = bis.read(buff);
            while (i != -1) {
                os.write(buff, 0, i);
                os.flush();
                i = bis.read(buff);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 上传二维码
     * @param requests
     * @param response
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public Map<String,Object> importQRcode(MultipartHttpServletRequest requests, HttpServletResponse response){
        long startTime = System.currentTimeMillis();    //获取开始时间
        HttpSession session = requests.getSession();
        User user = (User)session.getAttribute("loginUser");
        Map<String,Object> baseResult = new HashMap<>();
        Iterator<String> itr =  requests.getFileNames();
        MultipartFile mpf = null;
        while(itr.hasNext()) {
            mpf = requests.getFile(itr.next());
        }
        List<UnitInfo> unitInfoList = resolveExcel(mpf);
        if(unitInfoList != null && unitInfoList.size() > 0){
            String userId = user == null ? "no user" : user.getUserId().toString();
            String time = DateFormat.getDateTimeInstance().format(new Date());
            for(UnitInfo unitInfo : unitInfoList){
                unitInfo.setProducer(userId);
                unitInfo.setEnterTime(time);
            }
            baseResult.put("success","yes");
            baseResult.put("message","上传成功！");
        }else{
            baseResult.put("success","no");
            baseResult.put("message","上传失败！");
        }
        long endTime = System.currentTimeMillis();    //获取结束时间
        System.out.println("list==========="+Arrays.toString(unitInfoList.toArray()));
        System.out.println("list size==========="+unitInfoList.size());
        System.out.println("程序运行时间：" + (endTime - startTime) + "ms");    //输出程序运行时间
        return baseResult;
    }

    //解析Excel
    public List<UnitInfo> resolveExcel(MultipartFile file){

        List<UnitInfo> list = new ArrayList<>();
        //获取文件的名字
        String originalFilename = file.getOriginalFilename();
        Workbook workbook = null;
        try{
            if (originalFilename.endsWith(SUFFIX_2003)) {
                workbook = new HSSFWorkbook(file.getInputStream());
            } else if (originalFilename.endsWith(SUFFIX_2007)) {
                workbook = new XSSFWorkbook(file.getInputStream());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        if (workbook == null) {
            return null;
        }
        //获取所有的工作表的的数量
        int numOfSheet = workbook.getNumberOfSheets();
        //遍历这个这些表
        for (int i = 0; i < numOfSheet; i++) {
            //获取一个sheet也就是一个工作簿
            Sheet sheet = workbook.getSheetAt(i);
            int lastRowNum = sheet.getLastRowNum();
            //从第一行开始第一行一般是标题
            for (int j = 1; j <= lastRowNum; j++) {
                Row row = sheet.getRow(j);
                UnitInfo unitInfo = new UnitInfo();
                //获取二维码	商品生产时间	商品编号	生产批次	生产环境	原料批次
                if (row.getCell(0) != null) {
                    row.getCell(0).setCellType(CellType.STRING);
                    String qr = row.getCell(0).getStringCellValue();
                    unitInfo.setQR(qr);
                }
                if (row.getCell(1) != null) {
                    row.getCell(1).setCellType(CellType.STRING);
                    String productTime = row.getCell(1).getStringCellValue();
                    unitInfo.setProductTime(productTime);
                }
                if (row.getCell(2) != null) {
                    row.getCell(2).setCellType(CellType.STRING);
                    String itemNo = row.getCell(2).getStringCellValue();
                    unitInfo.setItemNo(itemNo);
                }
                if (row.getCell(3) != null) {
                    row.getCell(3).setCellType(CellType.STRING);
                    String enterBatch = row.getCell(3).getStringCellValue();
                    unitInfo.setEnterBatch(enterBatch);
                }
                if (row.getCell(4) != null) {
                    row.getCell(4).setCellType(CellType.STRING);
                    String envir = row.getCell(4).getStringCellValue();
                    unitInfo.setEnvironment(envir);
                }
                if (row.getCell(5) != null) {
                    row.getCell(5).setCellType(CellType.STRING);
                    String material = row.getCell(5).getStringCellValue();
                    unitInfo.setMaterialBatch(material);
                }
                list.add(unitInfo);
            }
        }
        return list;
    }


    @RequestMapping(method = RequestMethod.POST,value = "/genCodesTest")
    @ResponseBody
    public Map<String,Object> genCodesTest(HttpServletRequest request, UnitInfo uParam, String packHierQuant){
        HttpSession session = request.getSession();
        User user = (User)session.getAttribute("loginUser");
        String userId = user == null ? "no user" : user.getUserId().toString();
        Map<String,Object> baseResult = new HashMap<>();

        List<UnitInfo> unitInfoList = new ArrayList<>();
        String[] packArr = packHierQuant.replaceAll("[0-9]|\\*", " ").replaceAll(" +", " ").trim().split(" ");
        String[] sNumArr = packHierQuant.replaceAll("[\\u4e00-\\u9fa5]|\\*", " ").replaceAll(" +", " ").trim().split(" ");
        //数组转化
        int[] numArr = new int[sNumArr.length];
        for(int i = 0 ; i < numArr.length ; i ++){
            numArr[i] = Integer.parseInt(sNumArr[i]);
        }

        if(packArr.length > 1){
            for(int i = 0 ; i < packArr.length; i ++){
                int unitNum = 1 ;
                for(int k = 0 ; k < i+1; k++){
                    unitNum = unitNum * numArr[k];
                }
                for(int j = 0 ; j < unitNum ; j ++){
                    UnitInfo unitInfo = new UnitInfo();
                    unitInfo.setMaterialBatch(uParam.getMaterialBatch());
                    unitInfo.setEnvironment(uParam.getEnvironment());
                    unitInfo.setItemNo(uParam.getItemNo());
                    unitInfo.setProductTime(uParam.getProductTime());
                    unitInfo.setEnterBatch(uParam.getEnterBatch());
                    unitInfo.setProducer(userId);
                    unitInfo.setPackLevel(packArr[i]);
                    //生成二维码
                    unitInfo.setQR(MaterialCodeUtil.createGS1Code(unitInfo.getItemNo(),unitInfo.getEnterBatch(),unitInfo.getPackLevel()));
                    if(i == packArr.length - 1){
                        unitInfo.setNumOfSonPacks(0);
                    }else{
                        unitInfo.setNumOfSonPacks(numArr[i+1]);
                    }
                    unitInfoList.add(unitInfo);
                }
            }
        }else{//
            for(int i = 0 ; i < numArr[0] ; i ++){
                UnitInfo unitInfo = new UnitInfo();
                unitInfo.setMaterialBatch(uParam.getMaterialBatch());
                unitInfo.setEnvironment(uParam.getEnvironment());
                unitInfo.setItemNo(uParam.getItemNo());
                unitInfo.setProductTime(uParam.getProductTime());
                unitInfo.setEnterBatch(uParam.getEnterBatch());
                unitInfo.setProducer(userId);
                unitInfo.setPackLevel(packArr[0]);
                unitInfo.setNumOfSonPacks(0);
                //生成二维码
                unitInfo.setQR(MaterialCodeUtil.createGS1Code(unitInfo.getItemNo(),unitInfo.getEnterBatch(),unitInfo.getPackLevel()));
                unitInfoList.add(unitInfo);
            }
        }
        Message message = fabricService.enterTotalList(unitInfoList, userId);
        if("1".equals(message.getState())){//失败
            ArrayList<UnitInfo> failed = (ArrayList<UnitInfo>) message.getContext();
            baseResult.put("failed", failed);
            return baseResult;
        }
        baseResult.put("success", unitInfoList);
        return baseResult;
    }


    @RequestMapping(value = "/qrCoderList")
    public ReplayUtils getQrCoderList(Qrcode qrcode){
        PageInfo<Qrcode> pageInfo = fabricService.findQrCode(qrcode);
        return new ReplayUtils(pageInfo.getTotal(), pageInfo.getList(),0);
    }

    @RequestMapping(value = "/toQrCoderList")
    public ModelAndView toQrCoderList(ModelAndView mv){
        mv.setViewName("product/qrcode");
        return mv;
    }

    @RequestMapping(value = "/deleteQrCode")
    public int deleteQrCode(String qrcodeId ){
        if(StringUtils.isEmpty(qrcodeId)){
            return 0;
        }
        int result=fabricService.deleteQrCode(Long.parseLong(qrcodeId));
        return result;
    }

    @RequestMapping(value ="/bindQrInfo")
    public ModelAndView bindQrInfo(ModelAndView mv){
        mv.setViewName("product/bindQrInfo");
        return mv;
    }

    @RequestMapping(value ="/bindQrInfoList")
    public ReplayUtils bindQrInfoList(QrProduct qrProduct){
        PageInfo<QrProduct> pageInfo = qrProductService.selectQrProductList(qrProduct);
        return new ReplayUtils(pageInfo.getTotal(), pageInfo.getList(),0);
    }

    @PostMapping("/QrInfoAdd")
    public String QrInfoAdd(QrProduct qrProduct){
        return ResultCodeEnum.getResponseMsg(qrProductService.insertQrProduct(qrProduct));
    }
}
